function Calendar(el, date) {
    this.el = '';
    this._el = el;
    this.calendar_el = ''
    date = date ? date.split('-').map(item => this.formatDay(item)).join('-') : '';
    this.date = date ? new Date(date) : new Date();
    this.days = 30;
    this.render(el);
}
Calendar.prototype = {
    //初始化控件
    render: function(el) {
        const fragEle = document.createDocumentFragment();
        var div = document.createElement('div');
        div.className = 'calendar';
        div.setAttribute('id', 'calendar' + el);
        let html = `<div class="calendar-top">
                        <select name="month" id="month${el}">
                            <option value="1">1月</option>
                            <option value="2">2月</option>
                            <option value="3">3月</option>
                            <option value="4">4月</option>
                            <option value="5">5月</option>
                            <option value="6">6月</option>
                            <option value="7">7月</option>
                            <option value="8">8月</option>
                            <option value="9">9月</option>
                            <option value="10">10月</option>
                            <option value="11">11月</option>
                            <option value="12">12月</option>
                        </select>
                        <div class="select-year">
                            <div class="btn btn-left" id="btn-left${el}">
                                <div class="arrow"></div>
                            </div>
                            <input type="text" class="auto-year" id="auto-year${el}">
                            <div class="btn btn-right" id="btn-right${el}">
                                <div class="arrow"></div>
                            </div>
                        </div>
                    </div>
                    <div class="calendar-content">
                        <div class="week">
                            <ul>
                                <li>日</li>
                                <li>一</li>
                                <li>二</li>
                                <li>三</li>
                                <li>四</li>
                                <li>五</li>
                                <li>六</li>
                            </ul>
                        </div>
                        <div class="day">
                            <ul id="set-day${el}">

                            </ul>
                        </div>
                        <div class="calendar-bottom">
                            <div id="confrim-btn${el}" class="confrim-btn">确定</div>
                            <div id="cancel-btn${el}" class="cancel-btn">取消</div>
                        </div>
                    </div>`
        div.innerHTML = html;
        fragEle.appendChild(div);
        document.body.appendChild(fragEle);
        this.month_el = this.getElId('month' + el);
        this.year_el = document.getElementById('auto-year' + el);
        this.el = this.getElId(el);
        this.setDate()
        this.calendar_el = this.getElId('calendar' + el);
        this.setDomPositon()
        this.addEvent();
    },
    //相关事件方法
    addEvent: function() {
        let vm = this;
        window.addEventListener('resize', vm.setDomPositon());
        this.month_el.addEventListener('change', function() {
            vm.changeMonth()
        })
        this.getElId('btn-left' + this._el).addEventListener('click', function() {
            vm.getBtnYear('lt');
        });
        this.getElId('btn-right' + this._el).addEventListener('click', function() {
            vm.getBtnYear('rt')
        });
        this.getElId('confrim-btn' + this._el).addEventListener('click', function() {
            vm.date = new Date(Object.values(vm.current).map(item => vm.formatDay(item)).join('-'));
            vm.fnSetDay();
            vm.hide();
        });
        this.getElId('cancel-btn' + this._el).addEventListener('click', function() {
            vm.hide();
            vm.setDate();
        });
        this.el.addEventListener('focus', function() {
            vm.show();
        })
    },
    //控件定位
    setDomPositon: function() {
        this.calendar_el.style.cssText = "top: " + (this.el.offsetTop + this.el.offsetHeight) + 'px;left:' + this.el.offsetLeft + 'px;display: none';
    },
    //展示日历
    show: function() {
        var calendars = document.querySelectorAll('.calendar');
        for (let item of calendars) {
            if (item != this.calendar_el) {
                let cancel_el = document.querySelector('#' + item.getAttribute('id') + ' .cancel-btn')
                cancel_el.click();
            }
        }
        var val = this.calendar_el.style.cssText;
        this.calendar_el.style.cssText = val + 'display: block;'
    },
    hide: function() {
        var val = this.calendar_el.style.cssText;
        this.calendar_el.style.cssText = val + 'display: none;'
    },
    //2021-10-20设置日期
    setDate: function() {
        this.current = {
            year: this.date.getFullYear(),
            month: this.date.getMonth() + 1,
            day: this.date.getDate()
        }
        let { year, month } = this.current;
        this.year_el.value = year;
        this.getDays(month)
        let opts = this.month_el.getElementsByTagName("option"); //得到数组option
        opts[month - 1].selected = true;
        this.fnSetDay();
    },
    //获取年份
    getYear: function(el) {
        return el ? this.year_el.value : new Date(this.date).getFullYear();
    },
    //年份按钮事件
    getBtnYear: function(type) {
        var year;
        if (type == 'lt') {
            year = this.getYear(1);
            if (year > 1970) year--;
        } else {
            year = this.getYear(1);
            year++;
        }
        this.year_el.value = year;
        this.current.year = year;
        this.changeMonth();
    },
    //选择月份
    changeMonth: function() {
        this.current.month = this.month_el.selectedIndex + 1
        this.getDays(this.current.month)
    },
    //获取选择月份的天数
    getCurMonthDay: function(month) {
        var days;
        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                days = 31;
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                days = 30;
                break;
            case 2:
                days = this.fnToggleYear(this.current.year) ? 29 : 28;
                break;
        }
        return days;
    },
    // 获取当前月份一共有多少天
    getDays: function(month) {
        // month = parseInt(month_2);
        this.current.month = month;
        this.days = this.getCurMonthDay(month);
        var html = '',
            total = 42;
        // 这个月从星期几开始
        let { year, _month, day } = this.current;
        var start_week = new Date(year, month - 1, 1).getDay();
        var prev_year = (month - 1) > 0 ? year : year - 1,
            prev_month = (month - 1) > 0 ? (month - 1) : 12,
            prev_month_days = this.getCurMonthDay(prev_month);
        var next_month_days = total - this.days - start_week,
            next_year = (month + 1) > 12 ? year + 1 : year,
            next_month = (month + 1) > 12 ? 1 : (month + 1);
        // 前面补充的日期
        for (var i = start_week; i >= 0; i--) {
            let _day = this.formatDay(prev_month_days - i);
            let date = { prev_year, prev_month, _day };
            html += '<li class="prev" ymd="' + (Object.values(date).join('-')) + '">' + _day + '</li>'
        }
        for (var i = 1; i <= this.days; i++) {
            let f_day = this.formatDay(i);
            let date = { year, month, f_day };
            html += '<li class="' + (day == i ? 'select' : '') + '" ymd="' + (Object.values(date).join('-')) + '">' + f_day + '</li>'
        }
        // 后面补充的日期
        for (var i = 1; i < next_month_days; i++) {
            let f_day = this.formatDay(i);
            let date = { next_year, next_month, f_day };
            html += '<li class="next" ymd="' + (Object.values(date).join('-')) + '">' + f_day + '</li>'
        }
        this.setHtml('set-day' + this._el, html);
        this.fnChooseDay();
    },
    setHtml: function(el, html) {
        this.getElId(el).innerHTML = html;
    },
    //选择日期
    fnChooseDay: function() {
        var vm = this;
        let lis = document.querySelectorAll('#set-day' + this._el + ' li');
        for (let item of lis) {
            item.onclick = function() {
                let cls = this.className;
                this.className = cls.indexOf('select') != -1 ? cls : cls + ' select';
                vm.current.day = this.innerText;
                if (cls.indexOf('prev') != -1 || cls.indexOf('next') != -1) {
                    let date = this.getAttribute('ymd').split('-').map(item => parseInt(item));
                    let [year, month, day] = date;
                    vm.current = { year, month, day };
                    vm.year_el.value = year;
                    vm.getDays(month)
                    vm.month_el.options[month - 1].selected = true;
                }
                for (let child of lis) {
                    if (child != this) {
                        let c_cls = child.className;
                        if (c_cls.indexOf('select') != -1) {
                            child.className = c_cls.replace(/select/g, "");
                        }
                    }
                }
            }
        }
    },
    formatDay: function(day) {
        return day.toString().padStart(2, '0');
    },
    // 判断闰年或平年
    fnToggleYear: function(year) {
        return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    },
    //设置input日期
    fnSetDay: function() {
        this.el.value = Object.values(this.current).map(item => this.formatDay(item)).join('-');
    },
    getElId: function(el) {
        return document.getElementById(el)
    }
}